﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using puzzle;
using test;

namespace Test
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            canvas.Children.Clear();
            //RectField field = new RectField(15, 15, 8, 6);
            //WarpField field = new WarpField(6, 6, 9, 4, 2);
            //RockField field = new RockField(3, 5);
            //draw(field);
            AreaGen area = new AreaGen();
            //area.mazeGen(500, 5, 1, 1,false, 2, 1, 0, 0.6); //plain, lake, desert
            
            //area.mazeGen(500, 20, 1, 1, false, 3, 0.1, 0, 0.4); //forest, cave
            //AreaGen area = new AreaGen(500, 30, true, 2, 0.1, 0, 0); //building
            //area.mazeGen(100, 10, 1, 1, false, 4, 1, 0, 0);//town

            //line

            //mountain
            area.hillGen2Simple(3000);
            draw(area);

        }

        private void Grid_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            canvas.Children.Clear();
            //RunField field = new RunField(10, 10, 2, this);
            //SlideField field = new SlideField(15, 15);
            WorldGen world = new WorldGen();
            //draw(world);
        }

        public void draw(RunField field)
        {
            for (int i = 0; i < field.Width; i++)
            {
                for (int j = 0; j < field.Height; j++)
                {
                    Rectangle rect = new Rectangle();
                    rect.Width = 10;
                    rect.Height = 10;
                    switch (field.getTile(i, j).Type)
                    {
                        case TileType.Normal: rect.Fill = Brushes.White; break;
                        case TileType.Warper: rect.Fill = Brushes.Yellow; break;
                        case TileType.Waypoint:
                            switch (field.getTile(i, j).WaypointID)
                            {
                                case 0: rect.Fill = Brushes.LightBlue; break;
                                case 1: rect.Fill = Brushes.Pink; break;
                                case 2: rect.Fill = Brushes.LightGreen; break;
                            }
                            break;
                        case TileType.Blocked: rect.Fill = Brushes.DarkGray; break;
                        case TileType.Switch: rect.Fill = Brushes.Orange; break;
                        case TileType.ColorSwitch:
                            switch (field.getTile(i, j).WaypointID)
                            {
                                case 0: rect.Fill = Brushes.Cyan; break;
                                case 1: rect.Fill = Brushes.Purple; break;
                                case 2: rect.Fill = Brushes.Green; break;
                            }
                            break;
                        case TileType.State_Passable: rect.Fill = Brushes.Coral; break;
                        case TileType.State_Blocked: rect.Fill = Brushes.DarkRed; break;
                    }
                    Canvas.SetBottom(rect, j * 12 + field.Height * 13 * (int)((field.Width * 13 * field.DrawCount) / 1000));
                    Canvas.SetLeft(rect, i * 12 + (field.Width * 13 * field.DrawCount) % 1000);
                    canvas.Children.Add(rect);
                }
            }
        }

        public void draw(RectField field)
        {
            Random random = new Random();
            foreach (Box box in field.getBoxes())
            {
                SolidColorBrush brush = new SolidColorBrush();
                brush.Color = Color.FromRgb((byte)random.Next(256), (byte)random.Next(256), (byte)random.Next(256));

                Rectangle rect = new Rectangle();
                rect.Width = 10 * box.Width + 2 * (box.Width - 1);
                rect.Height = 10 * box.Height + 2 * (box.Height - 1);
                rect.Fill = brush;

                Canvas.SetLeft(rect, box.X * 12 + 100);
                Canvas.SetTop(rect, box.Y * 12 + 100);
                canvas.Children.Add(rect);
            }
        }

        public void draw(WarpField field)
        {
            Random random = new Random();
            int size = 36;
            int bordersize = 4;
            foreach (Box box in field.getBoxes())
            {
                Rectangle rect = new Rectangle();
                rect.Width = size * box.Width + bordersize * (box.Width - 1);
                rect.Height = size * box.Height + bordersize * (box.Height - 1);
                rect.StrokeThickness = 2;
                switch (box.Blocked)
                {
                    case -1: rect.Stroke = Brushes.Black; break;
                    case 0: rect.Stroke = Brushes.White; break;
                    case 1: rect.Stroke = Brushes.Orange; break;
                }
                if (box.ID == field.getFirstBox().ID) rect.Fill = Brushes.LightBlue;
                if (box.ID == field.getLastBox().ID) rect.Fill = Brushes.LightCoral;

                Canvas.SetLeft(rect, box.X * (size + bordersize) + 100);
                Canvas.SetTop(rect, box.Y * (size + bordersize) + 100);
                canvas.Children.Add(rect);
            }



            foreach (Warper warper in field.getWarpers())
            {
                SolidColorBrush brush = new SolidColorBrush();
                brush.Color = Color.FromRgb((byte)random.Next(256), (byte)random.Next(256), (byte)random.Next(256));
                drawWarper(brush, warper.Box1, warper.Slot1, warper.ColorID);
                drawWarper(brush, warper.Box2, warper.Slot2, warper.ColorID);
            }

            foreach (Box box in field.getColorSwitchers().Keys)
            {
                drawColorSwitcher(box, field.getColorSwitchers()[box].Item1, field.getColorSwitchers()[box].Item2);
            }

            foreach (Box box in field.getBlockerSwitches().Keys)
            {
                drawBlockerSwitch(box, field.getBlockerSwitches()[box]);
            }
        }

        public void drawWarper(SolidColorBrush brush, Box box, int slot, int colorID)
        {
            int size = 36;
            int subsize = size / 6;
            int bordersize = 4;
            int radius = 5;

            Ellipse c = new Ellipse();
            c.Width = radius * 2;
            c.Height = radius * 2;
            switch (colorID)
            {
                case 0: c.Stroke = System.Windows.Media.Brushes.Red; break;
                case 1: c.Stroke = System.Windows.Media.Brushes.Cyan; break;
                case 2: c.Stroke = System.Windows.Media.Brushes.Lime; break;
            }
            c.Fill = brush;
            int indexX = (slot % (box.Width * 2));
            int indexY = (slot / (box.Width * 2));
            int x = (subsize * (1 + indexX * 3)) + ((subsize - radius * 2) / 2);
            int y = (subsize * (1 + indexY * 3)) + ((subsize - radius * 2) / 2);
            Canvas.SetLeft(c, box.X * (size + bordersize) + 100 + x);
            Canvas.SetTop(c, box.Y * (size + bordersize) + 100 + y);
            canvas.Children.Add(c);
        }

        public void drawColorSwitcher(Box box, int slot, int colorID)
        {
            int size = 36;
            int subsize = size / 6;
            int bordersize = 4;
            int radius = 5;

            Rectangle c = new Rectangle();
            c.Width = radius * 2;
            c.Height = radius * 2;
            switch (colorID)
            {
                case 0: c.Fill = System.Windows.Media.Brushes.Red; break;
                case 1: c.Fill = System.Windows.Media.Brushes.Cyan; break;
                case 2: c.Fill = System.Windows.Media.Brushes.Lime; break;
            }
            c.Stroke = System.Windows.Media.Brushes.Black;
            int indexX = (slot % (box.Width * 2));
            int indexY = (slot / (box.Width * 2));
            int x = (subsize * (1 + indexX * 3)) + ((subsize - radius * 2) / 2);
            int y = (subsize * (1 + indexY * 3)) + ((subsize - radius * 2) / 2);
            Canvas.SetLeft(c, box.X * (size + bordersize) + 100 + x);
            Canvas.SetTop(c, box.Y * (size + bordersize) + 100 + y);
            canvas.Children.Add(c);
        }

        public void drawBlockerSwitch(Box box, int slot)
        {
            int size = 36;
            int subsize = size / 6;
            int bordersize = 4;
            int radius = 5;

            Rectangle c = new Rectangle();
            c.Width = radius * 2;
            c.Height = radius * 2;
            c.StrokeThickness = 2;
            c.Fill = System.Windows.Media.Brushes.Red;
            c.Stroke = System.Windows.Media.Brushes.Orange;
            int indexX = (slot % (box.Width * 2));
            int indexY = (slot / (box.Width * 2));
            int x = (subsize * (1 + indexX * 3)) + ((subsize - radius * 2) / 2);
            int y = (subsize * (1 + indexY * 3)) + ((subsize - radius * 2) / 2);
            Canvas.SetLeft(c, box.X * (size + bordersize) + 100 + x);
            Canvas.SetTop(c, box.Y * (size + bordersize) + 100 + y);
            canvas.Children.Add(c);
        }


        public void draw(SlideField field)
        {
            for (int i = 0; i < field.Width; i++)
            {
                for (int j = 0; j < field.Height; j++)
                {
                    Rectangle rect = new Rectangle();
                    rect.Width = 10;
                    rect.Height = 10;

                    switch (field.getTile(i, j))
                    {
                        case SlideType.Slide: rect.Fill = Brushes.LightCyan; break;
                        case SlideType.Block: rect.Fill = Brushes.Gray; break;
                        case SlideType.Normal: rect.Fill = Brushes.Lime; break;
                        case SlideType.Lose: rect.Fill = Brushes.DarkRed; break;
                        case SlideType.Warp: rect.Fill = Brushes.Yellow; break;
                    }

                    Canvas.SetTop(rect, 30 + j * 12);
                    Canvas.SetLeft(rect, 30 + i * 12);
                    canvas.Children.Add(rect);

                    Rectangle rect2 = new Rectangle();
                    rect2.Width = 10;
                    rect2.Height = 10;

                    if (field.getBlockPool(i, j) && field.getNormalPool(i, j))
                    {
                        rect2.Fill = Brushes.LightCyan;
                    }
                    else if (field.getBlockPool(i, j))
                    {
                        rect2.Fill = Brushes.Gold;
                    }
                    else if (field.getNormalPool(i, j))
                    {
                        rect2.Fill = Brushes.Lime;
                    }
                    else
                    {
                        rect2.Fill = Brushes.DarkRed;
                    }

                    Canvas.SetTop(rect2, 30 + j * 12);
                    Canvas.SetLeft(rect2, 30 + field.Width * 13 + i * 12);
                    canvas.Children.Add(rect2);
                }
            }
        }

        public void draw(RockField field)
        {
            int size = 10;

            for (int i = 0; i < field.Width; i++)
            {
                for (int j = 0; j < field.Height; j++)
                {
                    Rectangle rect = new Rectangle();
                    rect.Width = size;
                    rect.Height = size;

                    switch (field.getTiles(i, j))
                    {
                        case RockTileType.Target: rect.Fill = Brushes.Yellow; break;
                        case RockTileType.Hole: rect.Fill = Brushes.DarkGreen; break;
                        case RockTileType.Destructible: rect.Fill = Brushes.BurlyWood; break;
                        case RockTileType.Hollow: rect.Fill = Brushes.Khaki; break;
                        case RockTileType.Normal: rect.Fill = Brushes.DarkGray; break;
                        case RockTileType.Border: rect.Fill = Brushes.Black; break;
                    }

                    if (field.isPassable(i, j) && !field.getUsed(i, j)) rect.Fill = Brushes.DarkRed;

                    Canvas.SetTop(rect, 30 + j * (size + 1));
                    Canvas.SetLeft(rect, 30 + i * (size + 1));
                    canvas.Children.Add(rect);

                    if (field.getRock(i, j) != RockType.None)
                    {
                        Ellipse e = new Ellipse();
                        e.Width = size - 2;
                        e.Height = size - 2;

                        if (field.getRock(i, j) == RockType.Target) e.Fill = Brushes.Orange;
                        else if (field.getRock(i, j) == RockType.Normal) e.Fill = Brushes.DarkRed;


                        Canvas.SetTop(e, 30 + j * (size + 1) + 1);
                        Canvas.SetLeft(e, 30 + i * (size + 1) + 1);
                        canvas.Children.Add(e);
                    }
                }
            }

            RockTile startTile = field.getStartTile();
            Ellipse start = new Ellipse();
            start.Width = size - 2;
            start.Height = size - 2;

            start.Fill = Brushes.Blue;

            Canvas.SetTop(start, 30 + startTile.Y * (size + 1) + 1);
            Canvas.SetLeft(start, 30 + startTile.X * (size + 1) + 1);
            canvas.Children.Add(start);
        }

        private void draw(AreaGen area)
        {
            int size = 5;
            for (int i = 0; i < area.Width; i++)
            {
                for (int j = 0; j < area.Height; j++)
                {
                    Rectangle rect = new Rectangle();
                    rect.Width = size;
                    rect.Height = size;
                    switch (area.getTileType(i, j))
                    {
                        case AreaTileType.Wall: rect.Fill = Brushes.DimGray; break;
                        case AreaTileType.Depth: rect.Fill = Brushes.Black; break;
                        case AreaTileType.Ground: rect.Fill = Brushes.DarkGray; break;
                        default: rect.Fill = Brushes.Black; break;
                    }


                    Canvas.SetTop(rect, 30 + j * (size + 1));
                    Canvas.SetLeft(rect, 30 + i * (size + 1));
                    canvas.Children.Add(rect);
                }
            }
        }

        private void draw(WorldGen world)
        {
            int size = 1;
            for (int i = 0; i < world.Width; i++)
            {
                for (int j = 0; j < world.Height; j++)
                {
                    Rectangle rect = new Rectangle();
                    rect.Width = size;
                    rect.Height = size;
                    switch (world.getTile(i, j))
                    {
                        case WorldTileType.Tree: rect.Fill = Brushes.DarkGreen; break;
                        case WorldTileType.Grass: rect.Fill = Brushes.Lime; break;
                        case WorldTileType.Sea: rect.Fill = Brushes.Blue; break;
                        default : rect.Fill = Brushes.Gray; break;
                    }


                    Canvas.SetTop(rect, 30 + j * (size + 0));
                    Canvas.SetLeft(rect, 30 + i * (size + 0));
                    canvas.Children.Add(rect);
                }
            }
        }
    }
}
